import { faker } from '@faker-js/faker';
import SleepData from '../models/sleepData.js';
import ActivityData from '../models/activityData.js';
import HealthData from '../models/healthData.js';
import Device from '../models/device.js';
import { deviceTimers, intervalMap, setDeviceTimer, pushDeviceTimer } from '../services/device.js';

export const mockDevInfo = (devType) => {
    return {
        sn: faker.string.alphanumeric({ length: 12, casing: 'upper' }), // 如：AB12-CD34-EF56-GH78,
        mac: faker.internet.mac(),
        deviceType: devType,
        status: 'active',
    };
};

export const mockHealthData = (userId = null, deviceId = null, deviceType = null) => {
    // 如果未提供userId，则生成一个随机ID
    if (userId === null) {
        // userId = faker.number.int({ min: 1, max: 100 });
        userId = 1;
    }

    // // 如果未提供deviceId，则生成一个随机ID
    // if (deviceId === null) {
    //   // deviceId = faker.number.int({ min: 1, max: 50 });
    //   deviceId = 0;
    // }

    // 根据设备类型准备适当的健康数据
    let otherData = {};
    let healthStatus = 'normal';
    let heartRate = null;
    let bloodOxygen = null;
    let bloodPressureHigh = null;
    let bloodPressureLow = null;
    let bodyTemperature = null;

    // 随机决定健康状态，大多数情况下为正常
    const statusRandom = faker.number.int({ min: 1, max: 100 });
    if (statusRandom > 95) {
        healthStatus = 'severe';
    } else if (statusRandom > 85) {
        healthStatus = 'medium';
    } else if (statusRandom > 70) {
        healthStatus = 'slight';
    }

    // 如果没有指定设备类型或者明确要求生成完整数据，则生成所有健康指标
    if (deviceType === null || deviceId === null) {
        // 生成所有可能的健康数据
        heartRate = faker.number.int({ min: 60, max: 100 });
        bloodOxygen = faker.number.int({ min: 90, max: 100 });
        bloodPressureHigh = faker.number.int({ min: 90, max: 180 });
        bloodPressureLow = faker.number.int({ min: 60, max: 120 });
        bodyTemperature = parseFloat(
            faker.number.float({ min: 36, max: 40, multipleOf: 0.1 }).toFixed(1),
        );

        // 添加额外的健康数据到otherData
        otherData = {
            weight: parseFloat(
                faker.number.float({ min: 50, max: 100, multipleOf: 0.1 }).toFixed(1),
            ),
            bodyFat: parseFloat(
                faker.number.float({ min: 10, max: 30, multipleOf: 0.1 }).toFixed(1),
            ),
            muscleMass: parseFloat(
                faker.number.float({ min: 30, max: 50, multipleOf: 0.1 }).toFixed(1),
            ),
            bmi: parseFloat(faker.number.float({ min: 18, max: 30, multipleOf: 0.1 }).toFixed(1)),
            bloodGlucose: parseFloat(
                faker.number.float({ min: 4, max: 10, multipleOf: 0.1 }).toFixed(1),
            ),
            ecgWaveform: 'normal',
            qrsInterval: parseFloat(
                faker.number.float({ min: 0.08, max: 0.12, multipleOf: 0.01 }).toFixed(2),
            ),
        };
    } else {
        // 如果指定了设备类型，则根据设备类型生成特定数据
        switch (deviceType) {
            case 'BPMonitor': // 血压计
                bloodPressureHigh = faker.number.int({ min: 90, max: 180 }); // 收缩压
                bloodPressureLow = faker.number.int({ min: 60, max: 120 }); // 舒张压
                heartRate = faker.number.int({ min: 60, max: 100 }); // 心率
                break;
            case 'spO2Monitor': // 血氧仪
                bloodOxygen = faker.number.int({ min: 90, max: 100 }); // 血氧饱和度
                heartRate = faker.number.int({ min: 60, max: 100 }); // 心率/脉搏
                break;
            case 'BFPMonitor': // 体脂秤
                otherData = {
                    weight: parseFloat(
                        faker.number.float({ min: 50, max: 100, multipleOf: 0.1 }).toFixed(1),
                    ),
                    bodyFat: parseFloat(
                        faker.number.float({ min: 10, max: 30, multipleOf: 0.1 }).toFixed(1),
                    ),
                    muscleMass: parseFloat(
                        faker.number.float({ min: 30, max: 50, multipleOf: 0.1 }).toFixed(1),
                    ),
                    bmi: parseFloat(
                        faker.number.float({ min: 18, max: 30, multipleOf: 0.1 }).toFixed(1),
                    ),
                };
                break;
            case 'Thermometer': // 体温计
                bodyTemperature = parseFloat(
                    faker.number.float({ min: 36, max: 40, multipleOf: 0.1 }).toFixed(1),
                ); // 体温
                break;
            case 'BGMeter': // 血糖仪
                otherData = {
                    bloodGlucose: parseFloat(
                        faker.number.float({ min: 4, max: 10, multipleOf: 0.1 }).toFixed(1),
                    ), // 血糖 mmol/L
                };
                break;
            case 'wearable': // 穿戴设备可能会监测多种指标
                heartRate = faker.number.int({ min: 60, max: 100 });
                bloodOxygen = faker.number.int({ min: 90, max: 100 });
                break;
            case 'ECGMonitor': // 心电图仪
                heartRate = faker.number.int({ min: 60, max: 100 });
                otherData = {
                    ecgWaveform: 'normal', // 简化的心电图波形描述
                    qrsInterval: parseFloat(
                        faker.number.float({ min: 0.08, max: 0.12, multipleOf: 0.01 }).toFixed(2),
                    ),
                };
                break;
            default:
                // 默认情况，生成一些基本的健康数据
                heartRate = faker.number.int({ min: 60, max: 100 });
        }
    }

    return {
        userId,
        deviceId,
        healthStatus,
        heartRate,
        bloodOxygen,
        bloodPressureHigh,
        bloodPressureLow,
        bodyTemperature,
        otherData,
        collectTime: new Date().toISOString(),
    };
};

// 新增睡眠数据mock函数
export const mockSleepData = (userId, deviceId) => {
    const now = new Date();
    const hour = now.getHours();

    // 判断当前是否应该生成睡眠数据
    // 1. 晚上9点到凌晨5点：生成夜间睡眠数据
    // 2. 中午12-15点：可能生成午睡数据
    // 3. 其他时间：可能生成小憩数据
    let sleepType;
    if (hour >= 21 || hour < 4) {
        sleepType = 'night';
    } else if (hour >= 12 && hour < 15) {
        // 70%的概率生成午睡数据
        sleepType = Math.random() < 0.7 ? 'nap' : null;
    } else {
        // 20%的概率生成小憩数据
        sleepType = Math.random() < 0.15 ? 'rest' : null;
    }

    // 如果没有需要生成的睡眠数据，返回null
    if (!sleepType) {
        return null;
    }

    let sleepStart, sleepEnd, sleepDuration;

    if (sleepType === 'night') {
        // 夜间睡眠
        // 睡眠开始时间（当前时间）
        sleepStart = new Date(now);

        // 睡眠时长6-9小时
        sleepDuration = faker.number.float({ min: 6, max: 9, multipleOf: 0.5 });
        sleepEnd = new Date(sleepStart.getTime() + sleepDuration * 60 * 60 * 1000);

        // 确保结束时间在早上5-9点之间
        const endHour = sleepEnd.getHours();
        if (endHour < 5 || endHour >= 9) {
            sleepEnd.setHours(
                5 + Math.floor(Math.random() * 4),
                Math.floor(Math.random() * 60),
                0,
                0,
            );
            sleepDuration = (sleepEnd - sleepStart) / (60 * 60 * 1000);
        }
    } else if (sleepType === 'nap') {
        // 午睡
        // 午睡开始时间（当前时间）
        sleepStart = new Date(now);

        // 午睡时长15分钟到2小时
        sleepDuration = faker.number.float({ min: 0.25, max: 2, multipleOf: 0.25 });
        sleepEnd = new Date(sleepStart.getTime() + sleepDuration * 60 * 60 * 1000);

        // 确保午睡时间在12-15点之间
        const endHour = sleepEnd.getHours();
        if (endHour >= 15) {
            sleepEnd.setHours(14, 59, 0, 0);
            sleepDuration = (sleepEnd - sleepStart) / (60 * 60 * 1000);
        }
    } else {
        // 小憩
        // 小憩开始时间（当前时间）
        sleepStart = new Date(now);

        // 小憩时长15-30分钟
        sleepDuration = faker.number.float({ min: 0.16, max: 0.5, multipleOf: 0.25 });
        sleepEnd = new Date(sleepStart.getTime() + sleepDuration * 60 * 60 * 1000);
    }

    // 根据睡眠类型和时长计算睡眠阶段
    let deepSleepPercentage, remSleepPercentage;
    if (sleepType === 'night') {
        // 夜间睡眠：深度睡眠15-25%，REM睡眠20-25%
        deepSleepPercentage = faker.number.int({ min: 15, max: 25 });
        remSleepPercentage = faker.number.int({ min: 20, max: 25 });
    } else {
        // 午睡和小憩：主要是浅睡眠，少量深度睡眠
        deepSleepPercentage = faker.number.int({ min: 2, max: 10 }); // 调整午睡/小憩的深睡比例
        remSleepPercentage = faker.number.int({ min: 3, max: 8 }); // 调整午睡/小憩的REM睡眠比例
    }

    const deepSleepDuration = parseFloat(((sleepDuration * deepSleepPercentage) / 100).toFixed(1));
    const remSleepDuration = parseFloat(((sleepDuration * remSleepPercentage) / 100).toFixed(1));
    const lightSleepDuration = parseFloat(
        (sleepDuration - deepSleepDuration - remSleepDuration).toFixed(1),
    );

    // 睡眠质量评分
    const wakeUpTimes =
        sleepType === 'night'
            ? faker.number.int({ min: 0, max: 3 }) // 夜间睡眠可能醒来0-3次
            : faker.number.int({ min: 0, max: 1 }); // 午睡和小憩最多醒来1次

    const baseScore = 70 + (deepSleepPercentage - 15) * 2;
    const wakeUpPenalty = wakeUpTimes * 5;
    const sleepQualityScore = Math.min(100, Math.max(50, baseScore - wakeUpPenalty));

    // stopDataCollection(deviceTimers[deviceId]);

    return {
        userId,
        deviceId,
        sleepType, // 新增字段：区分睡眠类型
        sleepStart: sleepStart.toISOString(),
        sleepEnd: sleepEnd.toISOString(),
        sleepDuration: sleepDuration,
        deepSleepDuration: deepSleepDuration,
        lightSleepDuration: lightSleepDuration,
        remSleepDuration: remSleepDuration,
        deepSleepPercentage: deepSleepPercentage,
        wakeUpTimes: wakeUpTimes,
        sleepQualityScore: sleepQualityScore,
        collectTime: sleepEnd.toISOString(),
    };
};

// 新增活动数据mock函数
export const mockActivityData = (userId, deviceId) => {
    // 获取当前时间
    const now = new Date();
    const hour = now.getHours();

    // 根据时间段生成不同的活动数据
    let steps, distance, calories, activeTime;

    if (hour >= 22 || hour < 6) {
        // 夜间时段（22:00-6:00）：活动量最小
        steps = faker.number.int({ min: 0, max: 100 });
        distance = faker.number.float({ min: 0, max: 0.1, multipleOf: 0.01 });
        calories = faker.number.int({ min: 0, max: 50 });
        activeTime = faker.number.int({ min: 0, max: 10 });
    } else if (hour >= 6 && hour < 9) {
        // 早晨时段（6:00-9:00）：中等活动量
        steps = faker.number.int({ min: 200, max: 2000 });
        distance = faker.number.float({ min: 0.3, max: 1.5, multipleOf: 0.01 });
        calories = faker.number.int({ min: 20, max: 300 });
        activeTime = faker.number.int({ min: 15, max: 45 });
    } else if (hour >= 9 && hour < 18) {
        // 日间时段（9:00-18:00）：较高活动量
        steps = faker.number.int({ min: 200, max: 6000 });
        distance = faker.number.float({ min: 0.7, max: 3.5, multipleOf: 0.01 });
        calories = faker.number.int({ min: 20, max: 600 });
        activeTime = faker.number.int({ min: 30, max: 120 });
    } else {
        // 晚间时段（18:00-22:00）：中等活动量
        steps = faker.number.int({ min: 200, max: 3000 });
        distance = faker.number.float({ min: 0.5, max: 2.0, multipleOf: 0.01 });
        calories = faker.number.int({ min: 20, max: 350 });
        activeTime = faker.number.int({ min: 20, max: 60 });
    }

    return {
        userId,
        deviceId,
        steps,
        distance: parseFloat(distance.toFixed(2)),
        calories,
        activeTime,
        collectTime: now.toISOString(),
    };
};

// 通用数据采集模拟函数
/**
 * 启动数据采集模拟，定期生成数据并存储到数据库
 * @param {string} deviceType 设备类型
 * @param {number} intervalMinutes 采集间隔（分钟）
 * @param {number} userId 用户ID
 * @param {number} deviceId 设备ID
 * @returns {number} 定时器ID，可用于停止采集
 */
export const startDataCollection = async (
    deviceType,
    intervalMinutes,
    userId,
    deviceId,
    genImmediately = false,
) => {
    // 将分钟转换为毫秒
    const intervalMs = intervalMinutes * 60 * 1000;

    console.log(
        '\x1b[36m%s\x1b[0m',
        ` 开始为用户 ${userId} 的设备 ${deviceId}(${deviceType}) 模拟数据采集，间隔: ${intervalMinutes} 分钟`,
    );

    // 立即生成一次数据
    if (genImmediately) {
        await generateAndSaveData(deviceType, userId, deviceId);
    }

    // 返回定时器ID，可以用于后续停止采集
    return setInterval(async () => {
        await generateAndSaveData(deviceType, userId, deviceId);
    }, intervalMs);
};

/**
 * 根据设备类型生成并保存相应的数据
 * @param {string} deviceType 设备类型
 * @param {number} userId 用户ID
 * @param {number} deviceId 设备ID
 */
async function generateAndSaveData(deviceType, userId, deviceId) {
    try {
        let mockData;
        let savedData;

        // 更新设备的最后同步时间
        await Device.update(
            { lastSyncTime: new Date().toISOString() },
            { where: { id: deviceId } },
        );

        // 根据设备类型生成对应的数据
        switch (deviceType) {
            case 'SleepMonitor': // 睡眠监测仪
            // case 'wearable': // 可穿戴设备也可能监测睡眠
            //     if (deviceType == 'wearable' && Math.random() < 0.1) {
            //         break;
            //     }

                mockData = mockSleepData(userId, deviceId);
                if (!mockData) {
                    break;
                }

                // 保存到睡眠数据表
                savedData = await SleepData.create(mockData);
                console.log(
                    `[${new Date().toISOString()}] 已生成并保存睡眠数据 ID:${savedData.id}，用户:${userId}，设备:${deviceId}`,
                );

                // 停止当前的数据采集
                if (deviceTimers[deviceId]) {
                    stopDataCollection(deviceTimers[deviceId]);
                }

                // 设置定时器，在睡眠结束后重新启动数据采集
                setTimeout(
                    async () => {
                        const timerId = await startDataCollection(
                            deviceType,
                            intervalMap[deviceType],
                            userId,
                            deviceId,
                        );
                        pushDeviceTimer(deviceId, timerId);
                    },
                    mockData.sleepDuration * 60 * 60 * 1000,
                );

                break;

            case 'ActivityTracker': // 活动追踪器
            case 'wearable': // 可穿戴设备通常也会追踪活动

                if (deviceType == 'wearable' && Math.random() >= 0.1) {
                    break;
                }
                mockData = mockActivityData(userId, deviceId);
                // 保存到活动数据表
                savedData = await ActivityData.create(mockData);
                console.log(
                    `[${new Date().toISOString()}] 已生成并保存活动数据 ID:${savedData.id}，用户:${userId}，设备:${deviceId}`,
                );

                if (deviceTimers[deviceId]) {
                    stopDataCollection(deviceTimers[deviceId]);
                }

                setTimeout(
                    async () => {
                        const timerId = await startDataCollection(
                            deviceType,
                            intervalMap[deviceType],
                            userId,
                            deviceId,
                        );
                        pushDeviceTimer(deviceId, timerId);
                    },
                    mockData.activeTime * 60 * 1000,
                );


                break;

            default:
                // 健康设备生成健康数据
                mockData = mockHealthData(userId, deviceId, deviceType);
                // 保存到健康数据表
                savedData = await HealthData.create(mockData);
                console.log(
                    `[${new Date().toISOString()}] 已生成并保存健康数据 ID:${savedData.id}，用户:${userId}，设备:${deviceType}`,
                );
        }

        // 如果是可穿戴设备，同时生成活动和健康数据
        if (deviceType === 'wearable') {
            // 额外生成健康数据
            const healthData = mockHealthData(userId, deviceId, deviceType);
            const savedHealthData = await HealthData.create(healthData);
            console.log(
                `[${new Date().toISOString()}] 已为可穿戴设备额外生成健康数据 ID:${savedHealthData.id}`,
            );
        }

        return savedData;
    } catch (error) {
        console.error(`生成模拟数据时出错:`, error);
        throw error;
    }
}

/**
 * 停止数据采集模拟
 * @param {number} timerId 由startDataCollection返回的定时器ID
 */
export const stopDataCollection = (timerId) => {
    if (timerId) {
        clearInterval(timerId);
        console.log(`已停止数据采集，定时器ID: ${timerId}`);
        return true;
    }
    return false;
};

/**
 * 为多个设备批量启动数据采集
 * @param {Array} deviceConfigs 设备配置数组，每个元素包含 {userId, deviceId, deviceType, intervalMinutes}
 * @returns {Object} 包含设备ID和对应定时器ID的映射
 */
export const startBatchDataCollection = async (deviceConfigs) => {
    const timerIds = {};

    for (const config of deviceConfigs) {
        const { userId, deviceId, deviceType, intervalMinutes } = config;
        const timerId = await startDataCollection(
            deviceType,
            intervalMinutes || 30, // 默认30分钟
            userId,
            deviceId,
        );

        timerIds[deviceId] = timerId;
    }

    return timerIds;
};

/**
 * 批量停止数据采集
 * @param {Object} timerIds 设备ID到定时器ID的映射
 */
export const stopBatchDataCollection = (timerIds) => {
    for (const deviceId in timerIds) {
        stopDataCollection(timerIds[deviceId]);
    }

    console.log(`已批量停止 ${Object.keys(timerIds).length} 个设备的数据采集`);
};

/**
 * 生成一批测试数据（立即生成，不使用定时器）
 * @param {Object} config 配置对象 {userId, deviceId, deviceType, count}
 * @returns {Array} 生成的数据数组
 */
export const generateTestData = async (config) => {
    const { userId, deviceId, deviceType, count = 10 } = config;
    const results = [];

    for (let i = 0; i < count; i++) {
        const data = await generateAndSaveData(deviceType, userId, deviceId);
        results.push(data);
    }

    console.log(`已为设备 ${deviceId} 生成 ${count} 条测试数据`);
    return results;
};

/**
 * 为指定用户创建各种类型的 mock 设备并启动定时采集
 * @param {number} userId 用户ID
 * @returns {Object} 包含设备ID到定时器ID映射的对象
 */
export const startMockDevicesForUser = async (userId, intervalMinutes) => {
    const deviceTypes = [
        'BPMonitor',
        'spO2Monitor',
        'BFPMonitor',
        'Thermometer',
        'BGMeter',
        'wearable',
        'ECGMonitor',
        'SleepMonitor',
        'ActivityTracker',
    ];

    const timerIds = {};

    for (const deviceType of deviceTypes) {
        // 创建 mock 设备信息
        const devInfo = mockDevInfo(deviceType);
        const newDevice = await Device.create({
            sn: devInfo.sn,
            mac: devInfo.mac,
            deviceType: devInfo.deviceType,
            status: devInfo.status,
            lastSyncTime: new Date().toISOString(),
            userId: userId,
        });

        console.log(`[初始化] 已创建设备 ID:${newDevice.id}, 类型:${deviceType}`);

        // 启动数据采集
        const timerId = await startDataCollection(
            deviceType,
            intervalMinutes || 30, // 默认30分钟采集一次
            userId,
            newDevice.id,
        );

        timerIds[newDevice.id] = timerId;
    }

    return timerIds;
};

/**
 * 启动所有 active 设备的模拟数据采集
 * @param {Object} intervalMap 每种设备类型的采集间隔（分钟）
 * @returns {Object} 设备ID到定时器ID的映射
 */
export const startMockForAllDevices = async (intervalMap = {},floatInterval=0,genImmediately = false,) => {
    const devices = await Device.findAll();
    const timerIds = {};

    for (const device of devices) {
        if (device.status === 'active') {
            let interval = intervalMap[device.deviceType] || intervalMap.default || 60;
            interval+= parseFloat((floatInterval*Math.random()).toFixed(1));

            const timerId = await startDataCollection(
                device.deviceType,
                //  随机浮动采集间隔
                interval ,
                device.userId,
                device.id,
                genImmediately = false,
            );

            timerIds[device.id] = timerId;
            console.log(
                '\x1b[34m%s\x1b[0m',
                `[启动] 设备 ${device.id}(${device.deviceType}) 已开始模拟数据采集，间隔: ${interval} 分钟`,
            );
        } else {
            console.log(`[跳过] 设备 ${device.id} 状态为 inactive，不进行数据采集`);
        }
    }

    return timerIds;
};

// 使用示例:
/*
// 1. 启动单个设备的数据采集
const timerId = await startDataCollection('BPMonitor', 15, 1, 1); // 每15分钟为用户1的设备1(血压计)生成数据

// 2. 停止数据采集
stopDataCollection(timerId);

// 3. 批量启动多个设备的数据采集
const timerIds = await startBatchDataCollection([
  { userId: 1, deviceId: 1, deviceType: 'BPMonitor', intervalMinutes: 30 },
  { userId: 1, deviceId: 2, deviceType: 'wearable', intervalMinutes: 15 },
  { userId: 2, deviceId: 3, deviceType: 'Thermometer', intervalMinutes: 60 }
]);

// 4. 批量停止
stopBatchDataCollection(timerIds);

// 5. 立即生成一批测试数据
await generateTestData({ userId: 1, deviceId: 1, deviceType: 'BPMonitor', count: 20 });
*/
